Skip to content

Working Direct2d Support#10

Merged
mfisher31 merged 8 commits intomainfrom
direct2d
Jan 26, 2026
Merged

Working Direct2d Support#10
mfisher31 merged 8 commits intomainfrom
direct2d

Conversation

@mfisher31
Copy link
Copy Markdown
Member

Several fixes in the Direct2d were added so that rendering is comparable with the other working backends.

- Implement pugl backend integration (win_direct2d.cpp)
  * Proper Direct2D factory and DirectWrite factory initialization
  * Device-dependent resource management with render target recreation
  * Handle D2DERR_RECREATE_TARGET for device loss scenarios
  * Return surface structure from puglGetContext for clean resource access
  * Resize render target on window size changes
  * Use 96 DPI for 1:1 pixel coordinate mapping

- Implement complete DrawingContext (direct2d.cpp)
  * Full path geometry support using ID2D1PathGeometry and ID2D1GeometrySink
  * All drawing primitives: move_to, line_to, cubic_to, quad_to, close_path
  * Fill and stroke operations with proper brush and stroke style creation
  * Transform support with save/restore in state stack
  * Clipping with proper push/pop management and depth tracking
  * DirectWrite text rendering with Roboto font and baseline alignment
  * Font metrics and text metrics calculation
  * Image rendering using ID2D1Bitmap with transformation support
  * State management including transform matrix in state stack

Key design decisions:
- Direct2D uses top-left origin naturally (no flipping needed)
- Render target uses 96 DPI for identity pixel mapping
- Transform matrix stored in State for proper save/restore
- Clip depth tracking for proper clip stack management
- Fix move_to to always update current_pos even without geometry sink
  This is critical for text rendering since Graphics::draw_text calls
  move_to to set the baseline position before calling show_text

- Fix font_metrics to properly check if metrics were retrieved before
  releasing COM objects (was always returning approximation)

- Temporarily use Segoe UI instead of Roboto for testing
  (Roboto needs to be loaded from memory like GDI does)
Direct2D matrix multiplication A * B applies B first, then A.
We were doing currentTransform * newTransform, which applied the
new transform before the current transform (backwards).

Fixed by reversing to newTransform * currentTransform, so the
current transform is applied first, then the new transform is
applied on top of it.

This fixes dial indicator lines now rotating correctly instead
of gliding up and down.
- Fix draw_image to use correct matrix multiplication order
  (newTransform * oldTransform instead of oldTransform * newTransform)
  This fixes image alignment issues where images snapped left

- Add comprehensive Graphics Backend Implementation Notes to
  copilot-instructions.md documenting all critical Direct2D and
  GDI backend lessons learned:
  * Matrix multiplication order (A * B applies B first, then A)
  * Text positioning requirements (move_to must update current_pos)
  * COM lifetime management for font metrics
  * Transform save/restore with D2D1_MATRIX_3X2_F
  * Clipping depth tracking
  * Path geometry lifecycle
  * DPI handling (96 DPI for 1:1 pixel mapping)
  * Resource management (device-independent vs device-dependent)
  * GDI+ comparison and patterns
@mfisher31 mfisher31 merged commit 53e3ce8 into main Jan 26, 2026
7 checks passed
@mfisher31 mfisher31 deleted the direct2d branch January 26, 2026 03:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant